package utils

import (
	"bytes"
	"fmt"
	"math/rand"
	"strings"
	"time"

	svg "github.com/ajstarks/svgo"
)

// GenerateSVG 生成SVG格式的验证码图片
func GenerateSVG(width, height int) ([]byte, string) {
	// 初始化随机数生成器
	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))

	// 生成4个随机字符
	code := generateRandomCode(4, rnd)

	// 创建SVG画布
	var buf bytes.Buffer
	canvas := svg.New(&buf)

	// 开始SVG文档
	canvas.Start(width, height)

	// 设置背景
	canvas.Rect(0, 0, width, height, "fill:#f8f9fa")

	// 添加干扰线
	drawInterferenceLines(canvas, width, height, rnd)

	// 添加干扰点
	drawInterferenceDots(canvas, width, height, rnd)

	// 绘制验证码字符
	drawCharacters(canvas, code, width, height, rnd)

	// 结束SVG文档
	canvas.End()

	return buf.Bytes(), code
}

// generateRandomCode 生成指定长度的随机验证码
func generateRandomCode(length int, rnd *rand.Rand) string {
	// 字符集：去除了容易混淆的字符
	charset := "23456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz"

	var code strings.Builder
	for i := 0; i < length; i++ {
		randomIndex := rnd.Intn(len(charset))
		code.WriteByte(charset[randomIndex])
	}

	return code.String()
}

// drawInterferenceLines 绘制干扰线
func drawInterferenceLines(canvas *svg.SVG, width, height int, rnd *rand.Rand) {
	lineCount := rnd.Intn(4) + 3 // 减少干扰线数量

	for i := 0; i < lineCount; i++ {
		x1 := rnd.Intn(width)
		y1 := rnd.Intn(height)
		x2 := rnd.Intn(width)
		y2 := rnd.Intn(height)

		colors := []string{"#e0e0e0", "#d0d0d0", "#c0c0c0"}
		color := colors[rnd.Intn(len(colors))]

		strokeWidth := rnd.Float64() + 0.5 // 减小线宽

		canvas.Line(x1, y1, x2, y2, fmt.Sprintf("stroke:%s;stroke-width:%.1f;opacity:0.5", color, strokeWidth))
	}
}

// drawInterferenceDots 绘制干扰点
func drawInterferenceDots(canvas *svg.SVG, width, height int, rnd *rand.Rand) {
	dotCount := rnd.Intn(21) + 20 // 进一步减少干扰点数量

	for i := 0; i < dotCount; i++ {
		x := rnd.Intn(width)
		y := rnd.Intn(height)
		radius := rnd.Float64() + 0.5 // 减小点半径

		colors := []string{"#f0f0f0", "#e8e8e8", "#e0e0e0"}
		color := colors[rnd.Intn(len(colors))]

		canvas.Circle(x, y, int(radius), fmt.Sprintf("fill:%s;opacity:0.4", color))
	}
}

// drawCharacters 绘制验证码字符 - 优化显示4个字符
func drawCharacters(canvas *svg.SVG, code string, width, height int, rnd *rand.Rand) {
	charCount := len(code)

	// 针对80x40画布优化字符位置
	charWidth := 14 // 进一步减小字符宽度
	spacing := 4    // 减小字符间距
	totalWidth := charCount*charWidth + (charCount-1)*spacing

	// 计算起始位置，确保居中
	startX := (width - totalWidth) / 2
	if startX < 8 {
		startX = 8
	}

	// 确保有足够的右边距
	if startX+totalWidth > width-5 {
		startX = 5
		charWidth = (width - 10 - (charCount-1)*spacing) / charCount
	}

	for i, char := range code {
		// 计算字符位置
		x := startX + i*(charWidth+spacing) + charWidth/2
		y := height/2 + 4 // 垂直居中

		// 进一步减小旋转角度范围 (-10° 到 10°)
		rotation := rnd.Intn(21) - 10

		// 减小字体大小 (18-22px)
		fontSize := rnd.Intn(5) + 18

		colors := []string{"#333333", "#444444", "#555555", "#0066cc", "#c44500", "#208740"}
		color := colors[rnd.Intn(len(colors))]

		// 设置文本样式
		style := fmt.Sprintf("font-size:%dpx;fill:%s;font-family:Arial, sans-serif;font-weight:bold;text-anchor:middle;dominant-baseline:middle", fontSize, color)

		// 如果有旋转，添加transform
		if rotation != 0 {
			transform := fmt.Sprintf("rotate(%d %d %d)", rotation, x, y)
			canvas.Text(x, y, string(char), fmt.Sprintf("transform:%s;%s", transform, style))
		} else {
			canvas.Text(x, y, string(char), style)
		}
	}
}

// GenerateOptimizedSVG 优化版验证码（更好的80x40显示）
func GenerateOptimizedSVG(width, height int) ([]byte, string) {
	// 初始化随机数生成器
	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))

	// 生成4个随机字符
	code := generateRandomCode(4, rnd)

	// 创建SVG画布
	var buf bytes.Buffer
	canvas := svg.New(&buf)

	// 开始SVG文档
	canvas.Start(width, height)
	canvas.Rect(0, 0, width, height, "fill:#f8f9fa")

	// 添加少量干扰线（更细更淡）
	for i := 0; i < 100; i++ {
		x1 := rnd.Intn(width)
		y1 := rnd.Intn(height)
		x2 := rnd.Intn(width)
		y2 := rnd.Intn(height)
		canvas.Line(x1, y1, x2, y2, "stroke:#e0e0e0;stroke-width:0.8;opacity:0.4")
	}

	// 添加少量干扰点
	for i := 0; i < 150; i++ {
		x := rnd.Intn(width)
		y := rnd.Intn(height)
		canvas.Circle(x, y, 1, "fill:#e0e0e0;opacity:0.3")
	}

	// 绘制验证码字符 - 针对80x40优化
	charCount := len(code)
	charWidth := 15
	spacing := 3
	totalWidth := charCount*charWidth + (charCount-1)*spacing
	startX := (width - totalWidth) / 2

	// 确保不超出边界
	if startX < 5 {
		startX = 5
	}
	if startX+totalWidth > width-5 {
		startX = 5
		charWidth = (width - 10 - (charCount-1)*spacing) / charCount
	}

	for i, char := range code {
		x := startX + i*(charWidth+spacing) + charWidth/2
		y := height/2 + 4

		// 小角度旋转 (-8° 到 8°)
		rotation := rnd.Intn(17) - 50
		fontSize := 20

		colors := []string{"#333333", "#444444", "#0066cc", "#c44500"}
		color := colors[rnd.Intn(len(colors))]

		if rotation != 0 {
			transform := fmt.Sprintf("rotate(%d %d %d)", rotation, x, y)
			style := fmt.Sprintf("font-size:%dpx;fill:%s;font-family:Arial, sans-serif;font-weight:bold;text-anchor:middle;dominant-baseline:middle", fontSize, color)
			canvas.Text(x, y, string(char), fmt.Sprintf("transform:%s;%s", transform, style))
		} else {
			style := fmt.Sprintf("font-size:%dpx;fill:%s;font-family:Arial, sans-serif;font-weight:bold;text-anchor:middle;dominant-baseline:middle", fontSize, color)
			canvas.Text(x, y, string(char), style)
		}
	}

	canvas.End()
	return buf.Bytes(), code
}

// VerifyCaptcha 验证验证码（使用strings.EqualFold进行不区分大小写比较）
func VerifyCaptcha(input, expected string) bool {
	if len(input) != 4 || len(expected) != 4 {
		return false
	}
	return strings.EqualFold(input, expected)
}

// GenerateSimpleSVG 简化版验证码（无旋转，最稳定）
func GenerateSimpleSVG(width, height int) ([]byte, string) {
	// 初始化随机数生成器
	rnd := rand.New(rand.NewSource(time.Now().UnixNano()))

	// 生成4个随机字符
	code := generateRandomCode(4, rnd)

	// 创建SVG画布
	var buf bytes.Buffer
	canvas := svg.New(&buf)

	// 开始SVG文档
	canvas.Start(width, height)
	canvas.Rect(0, 0, width, height, "fill:#f8f9fa")

	// 添加少量干扰线
	for i := 0; i < 2; i++ {
		x1 := rnd.Intn(width)
		y1 := rnd.Intn(height)
		x2 := rnd.Intn(width)
		y2 := rnd.Intn(height)
		canvas.Line(x1, y1, x2, y2, "stroke:#e0e0e0;stroke-width:1;opacity:0.4")
	}

	// 绘制验证码字符（无旋转，确保完全显示）
	charCount := len(code)
	charWidth := 16
	spacing := 4
	totalWidth := charCount*charWidth + (charCount-1)*spacing
	startX := (width - totalWidth) / 2

	for i, char := range code {
		x := startX + i*(charWidth+spacing) + charWidth/2
		y := height/2 + 4

		style := "font-size:20px;fill:#333333;font-family:Arial, sans-serif;font-weight:bold;text-anchor:middle;dominant-baseline:middle"
		canvas.Text(x, y, string(char), style)
	}

	canvas.End()
	return buf.Bytes(), code
}
